package jdec.jdt.ls.decompiler.jadx;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ls.core.internal.JDTUtils;
import jadx.api.JadxArgs;
import jadx.api.JadxDecompiler;
import jadx.api.JavaClass;
import jadx.api.JavaMethod;

class BytecodeProvider {

	private URI uri;
	private byte[] bytecode;

	public BytecodeProvider(URI uri) {
		this.uri = uri;
	}

	public BytecodeProvider(IClassFile classFile) {
		try {
			bytecode = loadClassFileBytes(classFile);
		} catch (IOException e) {
			// ignore
		}
	}

	public byte[] getBytecode(String externalPath, String internalPath) throws IOException {
		if (bytecode != null) {
			return bytecode;
		}
		bytecode = loadClassFileBytes(JDTUtils.resolveClassFile(uri));
		if (bytecode == null) {
			bytecode = loadBytecode(uri);
		}
		return bytecode;
	}

	private byte[] loadBytecode(URI uri) throws IOException {
		if (uri == null) {
			return null;
		}
		Path path = Paths.get(uri);
		return Files.readAllBytes(path);
	}

	private byte[] loadClassFileBytes(IClassFile classFile) throws IOException {
		if (classFile == null) {
			return null;
		}
		try {
			return classFile.getBytes();
		} catch (JavaModelException e) {
			throw new IOException(e);
		}
	}


	/**
	 * jax api 例子。 https://github.com/skylot/jadx/wiki/Use-jadx-as-a-library
	 */
	public static void main(String[] args) {
        JadxArgs jadxArgs = new JadxArgs();
        jadxArgs.setInputFile(new File("classes.dex"));
        jadxArgs.setOutDir(new File("output"));
        try (JadxDecompiler jadx = new JadxDecompiler(jadxArgs)) {
            jadx.load();

			boolean accessOnly = true;
			if (accessOnly) {
				for (JavaClass cls : jadx.getClasses()) {
					for (JavaMethod mth : cls.getMethods()) {
						System.out.println(mth.getName());
					}
				}
			} else {
				jadx.save();
			}
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
